#region Copyright
/// <copyright>
/// Copyright (c) 2007 Ilia Shramko.
/// Released under the terms of the GNU General Public License.
/// </copyright>
#endregion

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;

using Newtonsoft.Json;

namespace Osh.Media
{
	public class MediaAttributeCollection : DictionaryBase
	{

		public object this[MediaAttributeNames attributeName]
		{
			get { return this.GetValue(attributeName); }
			set { this.SetValue(attributeName, value); }
		}

		public void Add(MediaAttributeNames attribute, object value)
		{
			this.Add(new MediaAttribute(attribute, value));
		}

		public void Add(MediaAttribute attribute)
		{
			if(attribute == null)
				throw new ArgumentNullException("attribute");
			base.Dictionary[attribute.Name] = attribute;
		}

		public MediaAttribute Get(string attributeName)
		{
			MediaAttributeNames name;
			if(!TryParseAttributeName(attributeName, out name))
				return null;
			return Get(name);
		}

		[ComVisible(false)]
		public MediaAttribute Get(MediaAttributeNames attributeName)
		{
			return (MediaAttribute)base.Dictionary[attributeName];
		}

		public object GetValue(string attributeName)
		{
			MediaAttributeNames name;
			if(!TryParseAttributeName(attributeName, out name))
				return null;

			return GetValue(name);
		}

		[ComVisible(false)]
		public T GetValue<T>(MediaAttributeNames attributeName)
		{
			return (T)GetValue(attributeName);
		}

		[ComVisible(false)]
		public object GetValue(MediaAttributeNames attributeName)
		{
			MediaAttribute attribute = Get(attributeName);
			if(attribute != null)
				return attribute.Value;
			return null;
		}

		public void SetValue(string attributeName, object value)
		{
			MediaAttributeNames name;
			if(!TryParseAttributeName(attributeName, out name))
				throw new ArgumentOutOfRangeException("attributeName");
			SetValue(name, value);
		}

		[ComVisible(false)]
		public void SetValue(MediaAttributeNames attributeName, object value)
		{
			MediaAttribute attribute = Get(attributeName);
			if(attribute != null)
				attribute.Value = value;
			else
			{
				attribute = new MediaAttribute(attributeName, value);
				base.Dictionary[attributeName] = attribute;
			}
		}

		public string ToJsonString()
		{
			StringBuilder sb = new StringBuilder();
			using(JsonWriter writer = new JsonWriter(new StringWriter(sb)))
			{
				writer.WriteStartObject();
				foreach(DictionaryEntry entry in this)
				{
					MediaAttribute ma = (MediaAttribute)entry.Value;
					writer.WritePropertyName(ma.Name.ToString());
					if(ma.Value is Uri)
						writer.WriteValue((ma.Value as Uri).ToString());
					else
						writer.WriteRaw(JavaScriptConvert.ToString(ma.Value));
				}
				writer.WriteEndObject();
			}
			return sb.ToString();
		}

		protected bool TryParseAttributeName(string nameStr, out MediaAttributeNames name)
		{
			name = (MediaAttributeNames)(-1);
			try
			{
				name = (MediaAttributeNames)Enum.Parse(typeof(MediaAttributeNames), nameStr, true);
				return true;
			}
			catch
			{
				return false;
			}
		}
	}
}
